home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PCASM2.ZIP / CHAP7.DOC < prev    next >
Text File  |  1990-06-21  |  19KB  |  526 lines

  1.  
  2.  
  3.  
  4.                                                                             47
  5.  
  6.                                    CHAPTER 7 - LOGIC
  7.  
  8.  
  9.              There are a number of operations which work on individual bits of
  10.              a byte or word. Before we start working on them, it is necessary
  11.              for you to learn the Intel method of numbering bits. Intel starts
  12.              with the low order bit, which is #0, and numbers to the left. If
  13.              you look at a byte:
  14.  
  15.                  7 6 5 4 3 2 1 0
  16.  
  17.              that will be the ordering. If you look at a word:
  18.  
  19.                  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  20.  
  21.              that is the ordering. The overwhelming advantage of this is that
  22.              if you extend a number, the numbering system stays the same. That
  23.              means that if you take the number 45 :
  24.  
  25.                  7 6 5 4 3 2 1 0
  26.                  0 0 1 0 1 1 0 1  (45d)
  27.  
  28.              and sign extend it:
  29.  
  30.                  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  31.                   0  0  0  0  0  0  0  0  0  0  1  0  1  1  0  1 
  32.  
  33.              each of the bits keeps its previous numbering. The same is true
  34.              for negative numbers. Here's -73:
  35.  
  36.                  7 6 5 4 3 2 1 0
  37.                  1 0 1 1 0 1 1 1 (-73d)
  38.  
  39.                  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
  40.                   1  1  1  1  1  1  1  1  1  0  1  1  0  1  1  1  (-73d)
  41.  
  42.              In addition, the bit-position number denotes the power of 2 that
  43.              it represents. Bit 7 = 2 ** 7 = 128, bit 5 = 2 ** 5 = 32, 
  44.              bit 0 = 2 ** 0 = 1. {1}.
  45.  
  46.              Whenever a bit is mentioned by number, e.g. bit 5, this is what
  47.              is being talked about.
  48.  
  49.  
  50.              AND
  51.  
  52.              We will use AND as the prototype. There are five different ways
  53.              you can AND two numbers:
  54.  
  55.  
  56.              ____________________
  57.  
  58.                 1 I'm using the Fortran convention for showing exponents. That
  59.              is, 2 ** 7 is 2 to the 7th, 3 ** 19 is 3 to the 19th. 
  60.  
  61.              ______________________
  62.  
  63.              The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson
  64.  
  65.  
  66.  
  67.  
  68.              The PC Assembler Tutor                                         48
  69.              ______________________
  70.  
  71.                  1.   AND two register
  72.                  2.   AND a register with a variable
  73.                  3    AND a variable with a register
  74.                  4.   AND a register with a constant
  75.                  5.   AND a variable with a constant
  76.  
  77.              That is:
  78.  
  79.                  variable1 db   ?
  80.                  variable2 dw   ?
  81.  
  82.                  and  cl, dh
  83.                  and  al, variable1
  84.                  and  variable2, si
  85.                  and  dl, 0C2h
  86.                  and  variable1, 01001011b
  87.  
  88.              You will notice that this time the constants are expressed in hex
  89.              and binary. These are the only two reasonable alternatives. These
  90.              instructions work bit by bit, and hex and binary are the only two
  91.              ways of displaying a number bitwise (bit by bit). Of course, with
  92.              hex you must still convert a hex digit into four binary digits.
  93.  
  94.              The table of bitwise actions for AND is:
  95.  
  96.                  1    1    ->   1
  97.                  1    0    ->   0
  98.                  0    1    ->   0
  99.                  0    0    ->   0
  100.  
  101.              That is, a bit in the result will be set if and only if that bit
  102.              is set in both the source and the destination. What is this used
  103.              for? Several things. First, if you AND a register with itself,
  104.              you can check for zero.
  105.  
  106.                  and  cx, cx
  107.  
  108.              If any bit is set, then there will be a bit set in the result and
  109.              the zero flag will be cleared. If no bit is set, there will be no
  110.              bit set in the result, and the zero flag will be set. No bit will
  111.              be altered, and CX will be unchanged. This is the standard way of
  112.              checking for zero. You can't AND a variable that way:
  113.  
  114.                  and  variable1, variable1
  115.  
  116.              is an illegal instruction. But you can AND it with a constant
  117.              with all the bits set:
  118.  
  119.                  and  variable1, 11111111b
  120.  
  121.              If the bit is set in variable1, then it will be set in the
  122.              result. If it is not set in variable1, then it won't be set in
  123.              the result. This also sets the zero flag without changing the
  124.              variable.
  125.  
  126.              AND is also used in masks, which will be covered at the end of
  127.              the chapter.
  128.  
  129.  
  130.  
  131.  
  132.              Chapter 7 - Logic                                              49
  133.              _________________
  134.  
  135.  
  136.              Finally, there is a variant of AND called TEST. TEST does exactly
  137.              the same thing as AND but throws away the results when it is
  138.              done. It does not change the destination. This means that it can
  139.              check for specific things without altering the data. It has the
  140.              same possibilities as AND:
  141.  
  142.                  variable1 db   ?
  143.                  variable2 dw   ?
  144.  
  145.                  test cl, dh
  146.                  test al, variable1
  147.                  test variable2, si
  148.                  test dl, 0C2h
  149.                  test variable1, 01001011b
  150.  
  151.              will set the flags exactly the same as the similar AND
  152.              instructions but will not change the destination. We need a
  153.              concrete example, and for that we'll turn to your video card. In
  154.              text mode, your screen is 80 X 25. That is 2000 cells. Each cell
  155.              has a character byte and an attribute byte. The character byte
  156.              has the actual ascii number of the character. The attribute byte
  157.              says what color the character is, what color the background is,
  158.              whether the character is high or low intensity and whether it
  159.              blinks. An attribute byte looks like this:
  160.  
  161.                  7 6 5 4 3 2 1 0
  162.                  X R G B I R G B
  163.  
  164.              Bits 0,1 and 2 are the foreground (character) color. 0 is blue, 1
  165.              is green, and 2 is red. Bits 4, 5, and 6 are the background
  166.              color. 4 is blue, 5 is green, and 6 is red. Bit 3 is high
  167.              intensity, and bit 7 is blinking. If the bit is set (1) that
  168.              particular component is activated, if the bit is cleared (0),
  169.              that component is deactivated. 
  170.  
  171.              The first thing to notice is how much memory we have saved by
  172.              putting all this information together. It would have been
  173.              possible to use a byte for each one of these characteristics, but
  174.              that would have required 8 X 2000 bytes = 16000 bytes. If you add
  175.              the 2000 bytes for the characters themselves, that would be 18000
  176.              bytes. As it is, we get away with 4000 bytes, a savings of over
  177.              75%. Since there are four different screens (pages) on a color
  178.              card, that is 18000 X 4 = 72000 bytes compared to 4000 X 4 =
  179.              16000. That is a huge savings.
  180.  
  181.              We don't have the tools to access these bytes yet, but let's
  182.              pretend that we have moved an attribute byte into dl. We can find
  183.              out if any particular bit is set. TEST dl with a specific bit
  184.              pattern. If the zero flag is cleared, the result is not zero so
  185.              the bit was on. If the zero flag is set, the result is zero so
  186.              that bit was off
  187.  
  188.  
  189.                  test dl, 10000000b       ; is it blinking?
  190.                  test dl, 00010000b       ; is there blue in the background?
  191.                  test dl, 00000100b       ; is there red in the foreground?
  192.  
  193.  
  194.  
  195.  
  196.              The PC Assembler Tutor                                         50
  197.              ______________________
  198.  
  199.  
  200.              If we look at the zero flag, this will tell us if that component
  201.              is on. It won't tell us if the background is blue, because maybe
  202.              the green or the red is on too. Remember, test alters neither the
  203.              source nor the destination. Its purpose is to set the flags, and
  204.              the results go into the Great Bit Bucket in the Sky.
  205.  
  206.  
  207.              OR
  208.  
  209.              The table for OR is:
  210.  
  211.                  1    1    ->   1
  212.                  1    0    ->   1
  213.                  0    1    ->   1
  214.                  0    0    ->   0
  215.  
  216.              If either the source or the destination bit is set, then the
  217.              result bit is set. If both are zero then the result is zero.
  218.              OR is used to turn on a specific bit.
  219.  
  220.                  or   dl, 10000000b  ; turn on blinking
  221.                  or   dl, 00000001b  ; turn on blue foreground
  222.  
  223.              After this operation, those bits will be on whether or not they
  224.              were on before. It changes none of the bits where there is a 0.
  225.              They stay the same as before.
  226.  
  227.  
  228.              XOR
  229.  
  230.              The table for XOR is:
  231.  
  232.                  1    1    ->   0
  233.                  1    0    ->   1
  234.                  0    1    ->   1
  235.                  0    0    ->   0
  236.  
  237.              That is, if both are on or if both are off, then the result is
  238.              zero. If only one bit is on, then the result is 1. This is used
  239.              to toggle a bit off and on.
  240.  
  241.                  xor  dl, 10000000b  ; toggle blinking
  242.                  xor  dl, 00000001b  ; toggle blue foreground
  243.  
  244.              Where there is a 1, it will reverse the setting. Where there is a
  245.              0, the setting will stay the same. This leads to one of the
  246.              favorite pieces of code for programmers.
  247.  
  248.                  xor  ax, ax
  249.  
  250.              zeros the ax register. There are three ways to zero the ax
  251.              register:
  252.  
  253.                  mov  ax, 0
  254.                  sub  ax, ax
  255.                  xor  ax, ax
  256.  
  257.  
  258.  
  259.  
  260.              Chapter 7 - Logic                                              51
  261.              _________________
  262.  
  263.  
  264.              The first one is very clear, but slightly slower. For the second
  265.              one, if you subtract a number from itself, you always get zero.
  266.              This is slightly faster and fairly clear.{2}  For the third one,
  267.              any bit that is 1 will become 0, and and bit that is 0 will stay
  268.              0. It zeros the register as a side effect of the XOR instruction.
  269.              You'll never guess which one many programmers prefer. That's
  270.              right, XOR. Many programmers prefer the third because it helps
  271.              make the code more obsure and unreadable. That gives a certain
  272.              aura of technical complexity to the code.
  273.  
  274.  
  275.  
  276.              NEG and NOT
  277.  
  278.              NOT is a logical operation and NEG is an arithmetical operation.
  279.              We'll do both here so you can see the difference. NOT toggles the
  280.              value of each individual bit:
  281.  
  282.                  1    ->   0
  283.                  0    ->   1
  284.  
  285.              NEG negates the value of the register or variable (a signed
  286.              operation). NEG performs (0 - number) so:
  287.  
  288.                  neg  ax
  289.                  neg  variable1
  290.  
  291.              are equivalent to (0 - AX) and (0 - variable1) respectively. NEG
  292.              sets the flags in the same way as (0 - number).
  293.  
  294.              ; negvsnot.asm
  295.              ; compares the operations NEG and NOT
  296.              ; + + + + + + + + + + + + + + + START CODE BELOW THIS LINE 
  297.                     mov   ax_byte, 1          ; signed 
  298.                     mov   bx_byte, 1          ; signed 
  299.                     mov   cx_byte, 1          ; signed 
  300.                     mov   si_byte, 3          ; binary 
  301.                     mov   di_byte, 3          ; binary 
  302.                     mov   bp_byte, 3          ; binary 
  303.                     mov   dx, 0               ; not used, so clear
  304.                     lea   ax, ax_byte 
  305.                     call  set_reg_style 
  306.                     call  show_regs 
  307.               
  308.              outer_loop: 
  309.                     call  get_signed          ; get number 
  310.                     mov   bx, ax              ; move it to all registers 
  311.                     mov   cx, ax 
  312.                     mov   si, ax 
  313.                     mov   di, ax 
  314.                     mov   bp, ax 
  315.               
  316.                     not   bx                  ; NOT the second row down 
  317.              ____________________
  318.  
  319.                 2 This is one of the first instructions in the template files.
  320.  
  321.  
  322.  
  323.  
  324.              The PC Assembler Tutor                                         52
  325.              ______________________
  326.  
  327.                     not   di 
  328.                     neg   cx                  ; NEG the third row down 
  329.                     neg   bp 
  330.               
  331.                     call  show_regs 
  332.                     jmp   outer_loop 
  333.               
  334.              ; + + + + + + + + + + + + + + + END CODE ABOVE THIS LINE 
  335.  
  336.  
  337.              This is set up so the left registers are signed and the right
  338.              registers are binary. The top registers retain the original
  339.              value, the second registers down will do NOT and the third
  340.              registers down will do NEG.
  341.  
  342.              Put a number in. On the right side, you will see that NOT (in DI)
  343.              reverses the bit pattern, while on the left, NEG (in CX) negates
  344.              the number. Do a few more. This is always true. But they seem to
  345.              be related. In fact, BX will always be 1 too negative. Why?
  346.              Remember that in the introduction on numbers, when we changed
  347.              signs, we had:
  348.  
  349.                  negative of number = one's complement + 1
  350.  
  351.              but the one's complement is exactly NEG. It switches the value of
  352.              each bit. To get the values in the third row (CX and BP), simply
  353.              add 1 to the values in the second row (BX and DI). Remember, NOT
  354.              is a logical operation, NEG is an arithmetic operation.
  355.  
  356.  
  357.              MASKS
  358.  
  359.              To explain masks, we'll need some data, and we'll use the
  360.              attribute byte for the monitor. Here it is again:
  361.  
  362.                  7 6 5 4 3 2 1 0
  363.                  X R G B I R G B
  364.  
  365.              Bits 0,1 and 2 are the foreground (character) color. 0 is blue, 1
  366.              is green, and 2 is red. Bits 4, 5, and 6 are the background
  367.              color. 4 is blue, 5 is green, and 6 is red. Bit 3 is high
  368.              intensity, and bit 7 is blinking.
  369.  
  370.              What we want to do is turn certain bits on and off without
  371.              affecting other bits. What if we want to make the background
  372.              black without changing anything else? We use and AND mask.
  373.  
  374.                  and  video_byte, 10001111b
  375.  
  376.              Bits 0, 1, 2, 3 and 7 will remain unchanged, while bits 4, 5 and
  377.              6 will be zeroed. This will make the background black. What if we
  378.              wanted to make the background blue? This is a two step process.
  379.              First we make the background black, then set the blue background
  380.              bit. This involves first the AND mask, then an OR mask.
  381.  
  382.                  and  video_byte, 10001111b
  383.                  or   video_byte, 00010000b
  384.  
  385.  
  386.  
  387.  
  388.              Chapter 7 - Logic                                              53
  389.              _________________
  390.  
  391.  
  392.              The first instruction shuts off certain bits without changing
  393.              others. The second turns on certain bits without effecting
  394.              others. The binary constant that we are using is called a mask.
  395.              You may write this constant as a binary or a hex number. You
  396.              should never write it as a signed or unsigned number (unless you
  397.              are one of those people who just adores making code unreadable).
  398.  
  399.              If you want to turn off certain bits in a piece of data, use an
  400.              AND mask. The bits that you want left alone should be set to 1,
  401.              the bits that you want zeroed should be set to 0. Then AND the
  402.              mask with the data.
  403.  
  404.              If you want to turn on certain bits in a piece of data, use an OR
  405.              mask. The bits that you want left alone should be set to 0. The
  406.              bits that you want turned on should be set to 1. Then OR the mask
  407.              with the data.
  408.  
  409.              Go back to AND and OR to make sure you believe that this is what
  410.              will happen. 
  411.  
  412.  
  413.  
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.              The PC Assembler Tutor                                         54
  453.              ______________________
  454.  
  455.                                        SUMMARY
  456.  
  457.  
  458.              For AND, TEST, OR, and XOR you can have the following
  459.              combinations:
  460.  
  461.                  1.   two register
  462.                  2.   a register with a variable
  463.                  3    a variable with a register
  464.                  4.   a register with a constant
  465.                  5.   a variable with a constant
  466.  
  467.  
  468.              AND is a bitwise logical operation.
  469.  
  470.                  1    1    ->   1
  471.                  1    0    ->   0
  472.                  0    1    ->   0
  473.                  0    0    ->   0
  474.  
  475.              TEST does the same thing as AND except that the result is
  476.              discarded. It is used for setting the flags without altering the
  477.              data.
  478.  
  479.              OR is a bitwise logical operation.
  480.  
  481.                  1    1    ->   1
  482.                  1    0    ->   1
  483.                  0    1    ->   1
  484.                  0    0    ->   0
  485.  
  486.              XOR is a bitwise logical operation.
  487.  
  488.                  1    1    ->   0
  489.                  1    0    ->   1
  490.                  0    1    ->   1
  491.                  0    0    ->   0
  492.  
  493.  
  494.  
  495.              You can use NOT and NEG with either a register or a variable in
  496.              memory.
  497.  
  498.              NOT is a bitwise logical operation
  499.  
  500.                  0    ->   1
  501.                  1    ->   0
  502.  
  503.              NEG is an arithmetic operation. NUMBER -> - NUMBER. It gives the
  504.              negative of a signed number.
  505.  
  506.  
  507.              MASKS
  508.  
  509.                  If you want to turn off certain bits of a piece of data, use
  510.                  an AND mask. The bits that you want left alone should be set
  511.                  to 1, the bits that you want zeroed should be set to 0. Then
  512.  
  513.  
  514.  
  515.  
  516.              Chapter 7 - Logic                                              55
  517.              _________________
  518.  
  519.                  AND the mask with the data.
  520.  
  521.                  If you want to turn on certain bits of a piece of data, use
  522.                  an OR mask. The bits that you want left alone should be set
  523.                  to 0. The bits that you want turned on should be set to 1.
  524.                  Then OR the mask with the data.
  525.  
  526.